package cn.com.fattiger.object.clone;

import org.springframework.util.SerializationUtils;

/**
 * 
 * CloneDemo
 * @author fattiger.xiaoyang
 * @date 2016/12/23
 * qqGroup 454655009
 * clone深浅的区别
 * 浅是引用，只要改一处，所有的clone对象中的引用对象信息都修改
 * 深如何实现 1、对引用对象实现clone方法 2、序列化对象
 * 为什么要实现Cloneable 不实现会怎样？实现Cloneable接口，否则会抛出java.lang.CloneNotSupportedException。
 * 类似Java Serializable空接口 告诉虚拟机需要做什么
 * 深克隆/拷贝（deep clone/copy）： SerializationUtils
 * 浅克隆/拷贝（shallow clone/copy）：BeanUtils
 */
public class CloneDemo implements Cloneable{
	private int id;
	private String name;
	private CloneChild cloneChild;
	public CloneDemo(int id,CloneChild cloneChild){
		this.cloneChild = cloneChild;
		this.id = id;
	}
	public static void main(String[] args){
		CloneChild cc = new CloneChild(2);
		CloneDemo cd = new CloneDemo(1,cc);
		cd.setCloneChild(cc);
		CloneDemo cdc = (CloneDemo) cd.clone();
		cdc.getCloneChild().setId(333);
		SerializationUtils.deserialize(SerializationUtils.serialize(cd));
		System.out.println(cdc.getCloneChild().getId());
		System.out.println(cd.getCloneChild().getId());
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public CloneChild getCloneChild() {
		return cloneChild;
	}
	public void setCloneChild(CloneChild cloneChild) {
		this.cloneChild = cloneChild;
	}
	
	public Object clone(){
		CloneDemo cd = null;
		try {
			cd = (CloneDemo) super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		cd.setCloneChild((CloneChild) cd.getCloneChild().clone());
		return cd;
	}
}
class CloneChild implements Cloneable{
	private int id;
	private String name;
	public CloneChild(int id){
		this.id =id;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	public Object clone(){
		Object o = null;
		try {
			o = super.clone();
		} catch (CloneNotSupportedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return o;
	}
}
